package admin

import (
	"errors"
	"parking-lot-go-admin/model"
	"strings"
	"time"
)

type AdminWithGroupStruct struct {
	Id           int       `json:"id" gorm:"type:int(11) auto_increment; NOT NULL; primary_key"`
	AdminId      int       `json:"admin_id" gorm:"type:int(11); COMMENT:'管理员id'"`
	AdminGroupId int       `json:"admin_group_id" gorm:"type:int(11); COMMENT:'分组id'"`
	CreatedAt    time.Time `json:"created_at" gorm:"type:datetime"`
	UpdatedAt    time.Time `json:"updated_at" gorm:"type:datetime"`
}

func (c *AdminWithGroupStruct) TableName() string {
	return "admin_with_group"
}

// 修改权限
func (c *AdminWithGroupStruct) UpdateRole(adminId int, roles []int) error {
	var adminWithGroupStruct AdminWithGroupStruct

	//删除权限
	if err := model.Db.Table(c.TableName()).Where("admin_id", adminId).Not("admin_group_id in ?", roles).Delete(&adminWithGroupStruct).Error; err != nil {
		return err
	}

	//查询现有记录
	var AdminGroupIds []int
	model.Db.Table(c.TableName()).Where("admin_id", adminId).Pluck("admin_group_id", &AdminGroupIds)

	//插入新增权限
	insertGroupIds := c.difference(AdminGroupIds, roles)
	for _, v := range insertGroupIds {
		model.Db.Table(c.TableName()).
			Create(map[string]interface{}{
				"admin_id":       adminId,
				"admin_group_id": v,
				"created_at":     time.Now(),
				"updated_at":     time.Now(),
			})
	}

	return nil
}

func (c *AdminWithGroupStruct) difference(a, b []int) []int {
	m := make(map[int]bool)
	for _, x := range a {
		m[x] = true
	}
	diff := []int{}
	for _, x := range b {
		if !m[x] {
			diff = append(diff, x)
		}
	}
	return diff
}

// 查询用户权限
func (c *AdminWithGroupStruct) GetUserRoles(adminId any) ([]map[string]interface{}, error) {

	//查询所有分组
	var AdminGroupIds []int
	if err := model.Db.Debug().Table(c.TableName()).Where("admin_id", adminId).Pluck("admin_group_id", &AdminGroupIds).Error; err != nil {
		return nil, errors.New("查询关联分组失败" + err.Error())
	}

	//查询分组对应的权限
	var roleIds []string
	var adminGroupStruct AdminGroupStruct
	if err := model.Db.Debug().Table(adminGroupStruct.TableName()).Where("id", AdminGroupIds).Pluck("rules", &roleIds).Error; err != nil {
		return nil, errors.New("查询权限分组失败" + err.Error())
	}

	//查询菜单列表
	var adminAuthRuleStruct AdminAuthRuleStruct
	var adminAuthRuleData []AdminAuthRuleStruct
	db := model.Db.Table(adminAuthRuleStruct.TableName()).Debug()

	//如果有全部权限, 那么不加判断条件
	if model.IsStringInSlice("*", roleIds) == false {
		roleIdStr := ""
		for _, v := range roleIds {
			if v != "*" {
				roleIdStr += v + ","
			}
		}

		db = db.Where("id", strings.Split(roleIdStr, ","))
	}

	if err := db.Find(&adminAuthRuleData).Error; err != nil {
		return nil, errors.New("查询菜单列表失败" + err.Error())
	}

	//拼装返回菜单
	returnData := make([]map[string]interface{}, 0)
	for _, item := range adminAuthRuleData {
		if item.Level == 0 {
			rootNode := buildNode(item, adminAuthRuleData)
			returnData = append(returnData, rootNode)
		}
	}

	return returnData, nil
}

// 定义一个方法，用于构建节点及其子节点的数据结构
func buildNode(item AdminAuthRuleStruct, sortedData []AdminAuthRuleStruct) map[string]interface{} {
	node := make(map[string]interface{})
	for _, subItem := range sortedData {
		if subItem.ParentId == item.Id {
			// 递归调用 buildNode 方法构建子节点
			childNode := buildNode(subItem, sortedData)
			if len(childNode) > 0 {
				// 将子节点加入当前节点的 "children" 字段中
				if _, ok := node["children"]; !ok {
					node["children"] = make([]map[string]interface{}, 0)
				}
				node["children"] = append(node["children"].([]map[string]interface{}), childNode)
			}
		}
	}
	// 添加当前节点的其他字段
	node["path"] = item.Path
	node["rank"] = item.Rank
	if item.Name != "" {
		node["name"] = item.Name
	}
	if item.Component != "" {
		node["component"] = item.Component
	}
	meta := make(map[string]interface{})
	meta["showLink"] = item.ShowLink == 1
	meta["showParent"] = item.ShowParent == 1
	meta["title"] = item.Title
	meta["icon"] = item.Icon

	node["meta"] = meta

	return node
}
